import re, uiautomation as auto
import sys

from uiautomation import ControlType

TITLE_PATTERNS = [r'.*BOSS直聘.*']  # 标题模糊匹配
CHROME_CLASSES = {'Chrome_WidgetWin_0', 'Chrome_WidgetWin_1'}
MAX_DEPTH = 100
SEARCH_TMO = 3.0
PER_ITEM_TMO = 0.5


def list_top_windows():
    root = auto.GetRootControl()
    rows = []
    for w in root.GetChildren():
        try:
            rows.append((w.ControlTypeName, w.Name or '', w.ClassName or '', w))
        except Exception:
            pass
    for i, (t, n, c, _) in enumerate(rows, 1):
        print(f"{i:02d}. type={t:14} name='{n}' class='{c}'", file=sys.stderr)
    return rows


def name_matches(name: str) -> bool:
    return any(re.fullmatch(pat, name or '') for pat in TITLE_PATTERNS)


def get_boss_window(timeout: float = 3.0):
    """
    获取 BOSS直聘 根控件（WindowControl 或 PaneControl）
    :param timeout: 查找超时，秒
    :return: Control 对象或 None
    """
    with auto.UIAutomationInitializerInThread():
        auto.SetGlobalSearchTimeout(0.5)

        # 1) 先尝试 WindowControl（标准顶层窗口）
        win = auto.WindowControl(RegexName=r'.*BOSS直聘.*', searchDepth=1)
        if win.Exists(timeout, 0.2):
            return win

        # 2) 回退：在顶层 PaneControl 里找（Electron/Chromium 应用常见）
        root = auto.GetRootControl()
        for c in root.GetChildren():
            if 'BOSS直聘' in (c.Name or '') and c.ClassName in ('Chrome_WidgetWin_0', 'Chrome_WidgetWin_1'):
                return c

    print("❌ 未找到 BOSS直聘 窗口", file=sys.stderr)

    return None


def pick_boss_root():
    """返回最合理的 BOSS 根节点（Window 或 Pane）"""
    # 1) 先尝试 WindowControl（如果 BOSS 是真正的顶层窗口）
    for pat in TITLE_PATTERNS:
        win = auto.WindowControl(RegexName=pat, searchDepth=1)
        if win.Exists(SEARCH_TMO, 0.2):
            return win

    # 2) 回退：在顶层子控件中找 PaneControl + Class=Chrome_WidgetWin_* + Name 匹配
    tops = list_top_windows()  # 也顺便打印出来方便你核对
    candidates = []
    for _, name, cls, elem in tops:
        if cls in CHROME_CLASSES and name_matches(name):
            candidates.append(elem)

    if candidates:
        # 取面积最大者作为根
        def area(e):
            try:
                r = e.BoundingRectangle
                return max(0, (r.right - r.left)) * max(0, (r.bottom - r.top))
            except Exception:
                return -1

        return max(candidates, key=area)

    return None


def get_all_texts(root_ctrl, max_depth=None):
    """
    遍历 root_ctrl 下的所有子孙，收集 Text/Document 控件的 Name
    """
    texts = []

    def walk(ctrl, depth=0):
        if max_depth is not None and depth > max_depth:
            return
        try:
            children = ctrl.GetChildren()
        except Exception:
            return
        for c in children:
            try:
                if c.ControlTypeName in ('TextControl', 'GroupControl'):
                    if c.Name:  # 去掉空
                        texts.append(c.Name.strip())
            except Exception:
                pass
            walk(c, depth + 1)

    walk(root_ctrl)
    return texts


def is_visible(ctrl):
    try:
        if ctrl.IsOffscreen:
            return False
        r = ctrl.BoundingRectangle
        if r.right <= r.left or r.bottom <= r.top:
            return False
        # 判断是否在屏幕范围内
        from ctypes import windll
        sw = windll.user32.GetSystemMetrics(0)
        sh = windll.user32.GetSystemMetrics(1)
        if r.right <= 0 or r.bottom <= 0 or r.left >= sw or r.top >= sh:
            return False
        return True
    except Exception:
        return False


def execute(win, text, control_type, region):
    with auto.UIAutomationInitializerInThread():
        if win == None:
            win = get_boss_window()
        # win = get_boss_window()  # pick_boss_root()
        win.Exists(3, 0.2)  # 超时等待

        control_type_names = control_type

        # 将控件类型名称转换为对应的 ControlType 值
        control_types = []
        type_name_to_value = {
            'Button': ControlType.ButtonControl,
            'Text': ControlType.TextControl,
            'Hyperlink': ControlType.HyperlinkControl,
            'ListItem': ControlType.ListItemControl,
            'Edit': ControlType.EditControl,
            'CheckBox': ControlType.CheckBoxControl,
            'RadioButton': ControlType.RadioButtonControl,
            'ComboBox': ControlType.ComboBoxControl,
            'Menu': ControlType.MenuControl,
            'MenuItem': ControlType.MenuItemControl,
            'Tree': ControlType.TreeControl,
            'TreeItem': ControlType.TreeItemControl,
            'DataGrid': ControlType.DataGridControl,
            'DataItem': ControlType.DataItemControl,
            'Document': ControlType.DocumentControl,
            'Group': ControlType.GroupControl,
            'Pane': ControlType.PaneControl,
            'Window': ControlType.WindowControl,
            'Custom': ControlType.CustomControl
            # 可以根据需要添加更多类型映射
        }

        for type_name in control_type_names:
            if type_name in type_name_to_value:
                control_types.append(type_name_to_value[type_name])

        # 定义比较函数
        def compare_function(control,depth):

            # 先检查控件是否可见
            if not is_visible(control):
                return False

            # 检查控件类型
            if control.ControlType not in control_types:
                return False

            # 检查文本匹配
            control_name = control.Name or ''
            if control_name != text:
                return False

            # 检查区域限制
            if region and len(region) >= 4:
                rect = control.BoundingRectangle
                # 检查控件是否在指定区域内
                if (rect.left < region[0] or rect.top < region[1] or
                        rect.right > region[2] or rect.bottom > region[3]):
                    return False

            return True

        try:
            # 创建搜索控件
            search_control = auto.Control(
                searchFromControl=win,
                Compare=compare_function
            )

            if search_control.Exists():
                return search_control.GetPosition()
            else:
                return []
        except Exception as e:
            print(f"搜索过程中出错: {e}",file=sys.stdout)
            return []


# print('开始执行')
# results = execute(None,'使用招聘者身份登录11',['Text1','Button','Hyperlink','ListItem'],[])
# print(results)
